/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.viettel.bkno.visionone.business;

import com.viettel.bkno.visionone.business.interfaces.IUserManager;
import com.viettel.bkno.visionone.dataaccess.DatabaseAccessor;
import com.viettel.bkno.visionone.entities.CachedInfo;
import com.viettel.bkno.visionone.entities.User;
import com.viettel.bkno.visionone.exception.CoreServiceException;
import com.viettel.bkno.visionone.exception.CoreServiceFault;
import com.viettel.bkno.visionone.exception.FaultType;
import com.viettel.bkno.visionone.untils.ConfigType;
import com.viettel.bkno.visionone.untils.KeyGenerator;
import com.viettel.bkno.visionone.untils.ConfigurationManager;
import com.viettel.vinamilk.memcached.MemcachedClientManager;
import java.util.logging.Level;
import org.apache.log4j.Logger;

/**
 *
 * @author hien
 */
public class UserManager implements IUserManager {

    Logger logger = Logger.getLogger(UserManager.class);

    @Override
    public String authen(String username, String password) throws CoreServiceException {
        String token = "";
        // Doc database
        User user = DatabaseAccessor.getInstance().getUserInfo(username, password);
        if (user!=null) {
            // 1. Sinh token
            token = KeyGenerator.getInstance().genSessionKey();

            // 2. Luu token vao cached
            int expried = Integer.valueOf(ConfigurationManager.getInstance().getConfigValue(ConfigType.SESSION_TIMEOUT));
            try {
                CachedInfo cachedInfo = new CachedInfo(user,token);
                MemcachedClientManager.getInstance().set(username, expried, cachedInfo);
            } catch (Exception ex) {
                logger.error("Can't set token & user info to memcached server.", ex);
                CoreServiceFault fault = new CoreServiceFault();
                fault.setFaultCode(FaultType.MEMCACHED_EXCEPTION.getCode());
                fault.setFaultCode(FaultType.MEMCACHED_EXCEPTION.getName());
                throw new CoreServiceException(fault);
            }
        } else {
            logger.warn("Invalid user/password.");
            CoreServiceFault fault = new CoreServiceFault();
            fault.setFaultCode(FaultType.INVALID_USER_EXCEPTION.getCode());
            fault.setFaultCode(FaultType.INVALID_USER_EXCEPTION.getName());
            throw new CoreServiceException(fault);
        }
        return token;
    }

    /**
     * This method will not be published.
     * @param user 
     * @throws com.viettel.bkno.visionone.exception.CoreServiceException 
     */
    @Override 
    public void addUser(User user) throws CoreServiceException {
        if (user.isValidFormat()) {
            DatabaseAccessor.getInstance().addUser(user);
        } else {
            CoreServiceFault fault = new CoreServiceFault();
            fault.setFaultCode(FaultType.USER_FORMAT_EXCEPTION.getCode());
            fault.setFaultString(FaultType.USER_FORMAT_EXCEPTION.getName());
            throw new CoreServiceException(fault);
        }
    }

    @Override
    public CachedInfo getSessionInfo(String user, String token) throws CoreServiceException {
        CachedInfo sessionInfo = null;
        try {
            // Timeout = 5s
            sessionInfo = (CachedInfo) MemcachedClientManager.getInstance().get(user, 5000);
        } catch (Exception ex) {
            logger.error("Get session form memcached server unsuccessful.", ex);
            CoreServiceFault fault = new CoreServiceFault();
            fault.setFaultCode(FaultType.SESSION_INVALID.getCode());
            fault.setFaultString(FaultType.SESSION_INVALID.getName());
            throw new CoreServiceException(fault);
        }
        if (sessionInfo != null) {
            if(!sessionInfo.getToken().equals(token)) {
                logger.error("Given token is not match stored token.");
                CoreServiceFault fault = new CoreServiceFault();
                fault.setFaultCode(FaultType.SESSION_INVALID.getCode());
                fault.setFaultString(FaultType.SESSION_INVALID.getName());
                throw new CoreServiceException(fault); 
            }
            try {
                // Set lai Session de tranh timeout
                MemcachedClientManager.getInstance().set(user, Integer.valueOf(ConfigurationManager.getInstance().getConfigValue(ConfigType.SESSION_TIMEOUT)), sessionInfo);
            } catch (Exception ex) {
                logger.warn("Reset session info unsuccessful", ex);
            }
            return sessionInfo;
        } else {
            logger.info("Session is not exist.");
            CoreServiceFault fault = new CoreServiceFault();
            fault.setFaultCode(FaultType.SESSION_INVALID.getCode());
            fault.setFaultString(FaultType.SESSION_INVALID.getName());
            throw new CoreServiceException(fault);
        }
    }
}
